<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="前端JS高级第5天   前置知识点复习函数的3种调用模式目的：为了确定this的指向 普通函数执行模式通过函数名字 或者 变量 或者 参数 直接获取到函数体引用 加上 圆括号 来 执行函数体内部代码。 叫做 普通函数执行模式。 该模式下， this 就是 window 构造函数模式当使用函数去 配合new实例化对象时，函数的执行模式 为 构造函数模式。 该模式下，this 就是 要实例化的对象 方">
<meta property="og:type" content="article">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="http://yoursite.com/2017/09/06/text4/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="前端JS高级第5天   前置知识点复习函数的3种调用模式目的：为了确定this的指向 普通函数执行模式通过函数名字 或者 变量 或者 参数 直接获取到函数体引用 加上 圆括号 来 执行函数体内部代码。 叫做 普通函数执行模式。 该模式下， this 就是 window 构造函数模式当使用函数去 配合new实例化对象时，函数的执行模式 为 构造函数模式。 该模式下，this 就是 要实例化的对象 方">
<meta property="og:updated_time" content="2017-09-06T13:43:32.477Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Hexo">
<meta name="twitter:description" content="前端JS高级第5天   前置知识点复习函数的3种调用模式目的：为了确定this的指向 普通函数执行模式通过函数名字 或者 变量 或者 参数 直接获取到函数体引用 加上 圆括号 来 执行函数体内部代码。 叫做 普通函数执行模式。 该模式下， this 就是 window 构造函数模式当使用函数去 配合new实例化对象时，函数的执行模式 为 构造函数模式。 该模式下，this 就是 要实例化的对象 方">
  
    <link rel="alternate" href="/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
  

</head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-text4" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2017/09/06/text4/" class="article-date">
  <time datetime="2017-09-06T13:41:14.415Z" itemprop="datePublished">2017-09-06</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <p></p><p style="border-bottom:1px solid #ccc;font-size:2.5em;font-weight:bold;">前端JS高级第5天</p><p></p>
<hr>

<h1 id="前置知识点复习"><a href="#前置知识点复习" class="headerlink" title="前置知识点复习"></a>前置知识点复习</h1><h2 id="函数的3种调用模式"><a href="#函数的3种调用模式" class="headerlink" title="函数的3种调用模式"></a>函数的3种调用模式</h2><p>目的：为了确定this的指向</p>
<h3 id="普通函数执行模式"><a href="#普通函数执行模式" class="headerlink" title="普通函数执行模式"></a>普通函数执行模式</h3><p>通过函数名字 或者 变量 或者 参数 直接获取到函数体引用 加上 圆括号 来 执行函数体内部代码。</p>
<p>叫做 普通函数执行模式。</p>
<p>该模式下， this 就是 window</p>
<h3 id="构造函数模式"><a href="#构造函数模式" class="headerlink" title="构造函数模式"></a>构造函数模式</h3><p>当使用函数去 配合new实例化对象时，函数的执行模式 为 构造函数模式。</p>
<p>该模式下，this 就是 要实例化的对象</p>
<h3 id="方法调用模式"><a href="#方法调用模式" class="headerlink" title="方法调用模式"></a>方法调用模式</h3><p>通过对象 去调用方法，此时 对象对应的属性值 就是 一个函数，此函数的执行模式 就是 方法调用模式。</p>
<p>在该模式下，this 就是 方法的调用者</p>
<h2 id="原型"><a href="#原型" class="headerlink" title="原型"></a>原型</h2><h3 id="原型的概念"><a href="#原型的概念" class="headerlink" title="原型的概念"></a>原型的概念</h3><p>对象的原型 就是 其构造函数的prototype属性所指向的对象。</p>
<p>当生命一个函数时，就会创建一个对象，（默认除了constructor 和 __proto__属性，在没有其他成员），再将该对象赋值给函数的prototype属性。</p>
<h3 id="原型的作用"><a href="#原型的作用" class="headerlink" title="原型的作用"></a>原型的作用</h3><p>为了实现数据共享。（在使用原型共享数据时，通常是在同类对象之间共享的。）</p>
<p>在js设计之初，就考虑到对象之间有一些数据是相同的，所以提出原型的概念，来实现代码的复用。</p>
<p>因此，对象在访问属性时，不仅可以访问自身的，也可以访问其原型上的成员。</p>
<h3 id="本质"><a href="#本质" class="headerlink" title="本质"></a>本质</h3><p>通过概念，发现原型就是对象。</p>
<p>所以，在使用原型 实现数据共享时，可以在原有的原型上 扩展、或者 将原有的原型 替换为其他对象。</p>
<h3 id="获取方式"><a href="#获取方式" class="headerlink" title="获取方式"></a>获取方式</h3><ol>
<li><p>通过函数：fnName.prototype</p>
</li>
<li><p>通过对象：obj.__proto__ ==》obj.constructor.prototype</p>
</li>
</ol>
<p>__proto__ 是浏览器自己实现的属性，因此是非标准属性，在IE11之前 是没有该属性的。所以不能通过对象来获取自己的原型。那么就只能 通过对象的构造函数来获取。</p>
<h2 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h2><h3 id="概念"><a href="#概念" class="headerlink" title="概念"></a>概念</h3><p>所谓继承 就是指 一个对象有权去访问另一个对象的成员。</p>
<h3 id="作用"><a href="#作用" class="headerlink" title="作用"></a>作用</h3><p>实现代码的复用。方便去组织和管理代码。</p>
<h3 id="继承的实现"><a href="#继承的实现" class="headerlink" title="继承的实现"></a>继承的实现</h3><p>只要 能让对象 可以直接访问其他对象上的成员 的任何代码实现，都是叫做 继承的一种实现。</p>
<p>因此，在js种继承有很多的实现方式。常用的有2种：</p>
<ol>
<li>原型式</li>
</ol>
<ul>
<li>可以 在默认的原型上扩展成员 来实现继承</li>
<li>也可以将 默认的原型 替换为 被继承的对象 方式  来实现 –常用方式</li>
</ul>
<p>原型默认 具有constructor属性，而在替换掉默认原型后，该属性可能会丢失。如果在实际开发时，该属性有用，那么就手动添加上。</p>
<p>只能让一个对象 成员 另一个对象的原型，因此在使用原型式继承时，只能实现单继承。如果想要实现多继承，可以考虑 使用混入式继承。</p>
<ol>
<li>混入式继承</li>
</ol>
<p>如果对象a 想要 继承对象b，那么就将对象b的成员 添加给 对象a。这就是 混入式继承。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// 实现多继承</span></div><div class="line"><span class="comment">// target 继承者 必须参数</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">extend</span>(<span class="params"> target </span>)</span>&#123;</div><div class="line">    <span class="comment">// 1 保证传入了继承者，如果没有传入，就提前返回，结束函数的执行</span></div><div class="line">    <span class="keyword">if</span>( !target )&#123;</div><div class="line">        <span class="keyword">return</span>;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="keyword">var</span> i = <span class="number">1</span>,  </div><div class="line">        l = <span class="built_in">arguments</span>.length;</div><div class="line"></div><div class="line">    <span class="keyword">var</span> k, obj;</div><div class="line"></div><div class="line">    <span class="keyword">for</span>( ; i &lt; l; i++ )&#123;</div><div class="line">        obj = <span class="built_in">arguments</span>[ i ];</div><div class="line">        <span class="keyword">for</span>( k <span class="keyword">in</span> obj )&#123;</div><div class="line">            target[ k ] = obj[ k ];</div><div class="line">        &#125;</div><div class="line">    &#125; </div><div class="line"></div><div class="line">    <span class="comment">// 将继承者 作为函数的返回值。可以使用这种写法：var child = extend( &#123;&#125;, parent );</span></div><div class="line">    <span class="comment">// 否则 只能先定义child对象，在传入extend方法｛var child = &#123;&#125;; extend( child, parent ) ｝</span></div><div class="line">    <span class="keyword">return</span> target;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h2 id="原型链"><a href="#原型链" class="headerlink" title="原型链"></a>原型链</h2><p>默认 原型的原型 就是 Object.prototype；</p>
<p>在任何对象 到 Object.prototype 之间存在一条 由非标准属性__proto__串联起来的并且体现继承层次关系的链式结构，那么该结构 被叫做 对象的原型链。</p>
<h3 id="对象属性的访问原则"><a href="#对象属性的访问原则" class="headerlink" title="对象属性的访问原则"></a>对象属性的访问原则</h3><p>在访问对象属性时，</p>
<ul>
<li>首先在当前对象本身上 查找该属性。如果找到，就返回该属性值，并停止查找；</li>
<li>如果没有找到，就向其原型上查找，如果找到，就返回该属性值，并停止查找；</li>
<li>如果依旧没有找到，就向原型的原型上查找，直到Object.prototype上；</li>
<li>如果找到，就返回属性值；如果没有找到，就返回undefined。</li>
</ul>
<h1 id="今天内容"><a href="#今天内容" class="headerlink" title="今天内容"></a>今天内容</h1><h2 id="了解Object-prototype的成员"><a href="#了解Object-prototype的成员" class="headerlink" title="了解Object.prototype的成员"></a>了解Object.prototype的成员</h2><p>所有对象都会有一条原型链，而在这条原型链的顶端 就是 Object.prototype。因此 所以对象要么直接继承自Object.prototype，要么就是间接继承。</p>
<h3 id="constructor属性"><a href="#constructor属性" class="headerlink" title="constructor属性"></a>constructor属性</h3><p>指向当前原型对应的构造函数。就是Object函数</p>
<h3 id="hasOwnProperty方法"><a href="#hasOwnProperty方法" class="headerlink" title="hasOwnProperty方法"></a>hasOwnProperty方法</h3><ol>
<li><p>功能：判断对象是否 自己本身具有指定的属性，而不是继承下来的。如果是，就返回true；否则返回false</p>
</li>
<li><p>语法：obj.hasOwmProperty( ‘propertyName’ );</p>
</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> obj = &#123; <span class="attr">name</span>: <span class="string">'obj'</span> &#125;;</div><div class="line"><span class="built_in">console</span>.log( obj.hasOwnProperty( <span class="string">'name'</span> ) );<span class="comment">// true</span></div><div class="line"><span class="built_in">console</span>.log( obj.hasOwnProperty( <span class="string">'constructor'</span> ) ); <span class="comment">// false</span></div></pre></td></tr></table></figure>
<h3 id="isPrototypeOf方法"><a href="#isPrototypeOf方法" class="headerlink" title="isPrototypeOf方法"></a>isPrototypeOf方法</h3><ol>
<li><p>功能：判断一个对象 是否为 另一个对象的原型；如果是，就返回true；否则就返回false。</p>
</li>
<li><p>语法：obj1.isPrototypeOf( obj2 ); 判断 obj1是否为 obj2的原型。</p>
</li>
</ol>
<p>检测 obj2 对象的原型链上是否含有 obj1，如果含有就返回true；否则就返回false</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> arr = [];</div><div class="line"><span class="built_in">console</span>.log( arr.isPrototypeOf( <span class="built_in">Array</span>.prototype ) ); <span class="comment">// false </span></div><div class="line"><span class="built_in">console</span>.log( <span class="built_in">Array</span>.prototype.isPrototypeOf( arr ) ); <span class="comment">// true</span></div><div class="line"><span class="comment">// arr -&gt; Array.prototype -&gt; Object.prototype -&gt; null</span></div><div class="line"><span class="built_in">console</span>.log( <span class="built_in">Object</span>.prototype.isPrototypeOf( arr ) ); <span class="comment">// true</span></div><div class="line"><span class="built_in">console</span>.log( arr.isPrototypeOf( <span class="built_in">Object</span>.prototype ) ); <span class="comment">// false</span></div></pre></td></tr></table></figure>
<h3 id="propertyIsEnumerable方法"><a href="#propertyIsEnumerable方法" class="headerlink" title="propertyIsEnumerable方法"></a>propertyIsEnumerable方法</h3><ol>
<li><p>可枚举的属性：可以通过for..in循环遍历出来的属性，都是可枚举的属性</p>
</li>
<li><p>功能：判断对象的属性 是否为自己本身具有的 并且是可枚举的属性；如果同时满足2个条件，返回值为true；否则返回false。</p>
</li>
<li><p>语法：obj.propertyIsEnumerable( ‘propertyNaem’ );</p>
</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> obj = &#123; <span class="attr">name</span>: <span class="string">'obj'</span> &#125;;</div><div class="line"><span class="built_in">console</span>.log( obj.propertyIsEnumerable( <span class="string">'name'</span> ) ); <span class="comment">// true</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Dog</span>(<span class="params"></span>)</span>&#123;&#125;</div><div class="line">Dog.prototype.color = <span class="string">'red'</span>;</div><div class="line"><span class="keyword">var</span> TaiDi = <span class="keyword">new</span> Dog();</div><div class="line"><span class="built_in">console</span>.log( TaiDi.propertyIsEnumeralbe( <span class="string">'color'</span> ) );<span class="comment">// false</span></div><div class="line"></div><div class="line"><span class="comment">// ES5 defineProperty</span></div><div class="line"><span class="built_in">Object</span>.defineProperty( obj, <span class="string">'age'</span>, &#123;</div><div class="line">    value: <span class="number">20</span>,</div><div class="line">    enumerable: <span class="literal">false</span></div><div class="line">&#125; );</div><div class="line"><span class="built_in">console</span>.log( obj.hasOwnProperty( <span class="string">'age'</span> ) ); <span class="comment">// true</span></div><div class="line"><span class="built_in">console</span>.log( obj.propertyIsEnumerable( <span class="string">'age'</span> ) ); <span class="comment">// false</span></div></pre></td></tr></table></figure>
<h3 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h3><ol>
<li>toLocaleString</li>
</ol>
<p>该方法是 Object.prototy 的方法。在内部实现 就是 直接调用了 toString方法。</p>
<p>为了其他原型 去重写该方法的。Date对象的原型（Date.prototype）重写了toLocalString方法，转换成本地时间的字符串。</p>
<ol>
<li>toString</li>
</ol>
<p>返回描述对象的基本信息的字符串。eg：“[object Object]”</p>
<p>第一个单词 是对象的类型 就是typeof返回值</p>
<p>第二个单词 是对象的构造函数名字</p>
<p><em>注意：有些对象的原型 重写了 Object.prototype上toString方法，因此也就说那些被重写的对象 是无法直接访问Object.prototype上的toString方法的。</em></p>
<ol>
<li>valueOf</li>
</ol>
<p>返回 对象的原始值。主要应用在隐式类型转换运算中。因此 作为一个原理性的知识，知道即可。</p>
<p>如果 是 数字对象 调用该方法，就会返回对应的原始值 数字；<br>如果 是 字符串对象，  就会返回 字符串；<br>如果 是 boolean对象，就返回 true 或 false；</p>
<p>如果是其他对象的话，就返回 该对象。也就说 将方法的调用者返回。</p>
<h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><p>函数的定义：就是 实现特定功能的代码块。</p>
<h3 id="函数-是-一等公民"><a href="#函数-是-一等公民" class="headerlink" title="函数 是 一等公民"></a>函数 是 一等公民</h3><p>在js中，函数的使用是非常灵活的，很多的js高级写法 都是由于函数而产生的。</p>
<ul>
<li>函数 可以作为 另一个函数的实参 - 回调函数</li>
<li>可以作为 另一个函数的返回值 - 闭包</li>
<li>作为对象的属性值，此时函数就成为对象的方法了</li>
<li>函数可以嵌套使用（嵌套调用 和 定义）</li>
<li>在js中，函数可以限定作用域。因此 局部作用域 也叫 函数作用域</li>
<li>具有 双重身份-既是函数 也是 对象</li>
</ul>
<p>在前两种使用方式，还有一种专业的叫法：高阶函数。fn.bind, arr.sort,str.replace,Array filter some every reduce forEach map …</p>
<h2 id="作为函数"><a href="#作为函数" class="headerlink" title="作为函数"></a>作为函数</h2><h3 id="创建函数"><a href="#创建函数" class="headerlink" title="创建函数"></a>创建函数</h3><ol>
<li>函数表达式</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> fn = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;;</div></pre></td></tr></table></figure>
<ol>
<li>函数声明式</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span>&#123;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>以上两种创建函数的区别：前者 只会将函数名字提升；而后者将函数名字以及函数体都提升。</p>
<ol>
<li>Function构造函数 – 不推荐</li>
</ol>
<p>var fnName = new Function( [arg1~argN], body );</p>
<p>[arg1~argN] 可选形参，类型为 字符串。作用：指定生成函数的形参部分。</p>
<p>body 可选参数，类型为  字符串。作用：定义生成函数的函数体部分。</p>
<p>如果 在new Function时，</p>
<ul>
<li>一个参数都没有传，就是生成一个没有定义形参的，并且函数体部分没有任何代码的函数；</li>
<li>仅传入一个参数值，就是生成一个没有定义形参的，但是函数体部分就是传入的参数值的函数。其实就是 给body参数 传入了实参。</li>
<li>如果传入两个以上的话，最后一个实参值是给body指定的，其余的实参值是在定义生成函数的形参部分。</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> f1 = <span class="keyword">new</span> <span class="built_in">Function</span>();</div><div class="line"><span class="comment">// ==&gt; var f1 = function()&#123;&#125;;</span></div><div class="line"><span class="keyword">var</span> f2 = <span class="keyword">new</span> <span class="built_in">Function</span>( <span class="string">'alert(1)'</span> );</div><div class="line"><span class="comment">// ==&gt; var f2 = function()&#123; alert(1) &#125;;</span></div><div class="line"><span class="keyword">var</span> f3 = <span class="keyword">new</span> <span class="built_in">Function</span>( <span class="string">'n'</span>, <span class="string">'alert( n )'</span> );</div><div class="line"><span class="comment">// ==&gt; var f3 = function( n )&#123; alert( n ); &#125;;</span></div><div class="line"><span class="keyword">var</span> f4 = <span class="keyword">new</span> <span class="built_in">Function</span>( <span class="string">'n'</span>, <span class="string">'m'</span>, <span class="string">'alert( n + m );'</span> );</div><div class="line"><span class="comment">// ==&gt; var f4 = function( n, m )&#123; alert( n + m ); &#125;;</span></div></pre></td></tr></table></figure>
<p><em>可以使用Function去模拟实现eval函数的功能（让一个字符串当作js代码来执行） ( new Function( str )() );</em></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> str = <span class="string">'alert( 1 )'</span>;</div><div class="line"><span class="comment">// use eval</span></div><div class="line"><span class="built_in">eval</span>( str );</div><div class="line"><span class="comment">// use Function </span></div><div class="line"><span class="comment">// 将str当作生成函数的函数体部分，然后在执行函数。那么str就可以当作js代码执行了</span></div><div class="line"><span class="comment">// var fn = new Function( str );</span></div><div class="line"><span class="comment">// fn();</span></div><div class="line"> ( <span class="keyword">new</span> <span class="built_in">Function</span>( str )() );</div></pre></td></tr></table></figure>
<h3 id="调用模式"><a href="#调用模式" class="headerlink" title="调用模式"></a>调用模式</h3><ol>
<li><p>普通函数调用模式</p>
</li>
<li><p>构造函数模式</p>
</li>
<li><p>方法调用模式</p>
</li>
<li><p>特殊调用–递归调用</p>
</li>
</ol>
<h3 id="形参-与-实参"><a href="#形参-与-实参" class="headerlink" title="形参 与 实参"></a>形参 与 实参</h3><p>形参： 所谓形参 就是 形式参数。在实际使用时，假设其有值，然后去参加运算。</p>
<p>s = a * h / 2.</p>
<p>实参： 就是 实际参数。在函数执行时，所传入的实际值，就是 实参。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params"> a, b </span>)</span>&#123;</div><div class="line">    <span class="comment">// 这里的a 和 b 就是形参</span></div><div class="line">    <span class="keyword">return</span> a + b;</div><div class="line">&#125;</div><div class="line"></div><div class="line">add( <span class="number">1</span>, <span class="number">2</span> ); <span class="comment">// 这里 在执行add函数时，所传入的1 和 2 值 才是实参。</span></div></pre></td></tr></table></figure>
<h2 id="作为对象"><a href="#作为对象" class="headerlink" title="作为对象"></a>作为对象</h2><p>函数 作为对象，那么就会具有一些默认的属性和方法。</p>
<h3 id="函数对象-相关属性-–重点看arguments"><a href="#函数对象-相关属性-–重点看arguments" class="headerlink" title="函数对象 相关属性 –重点看arguments"></a>函数对象 相关属性 –重点看arguments</h3><ol>
<li>arguments 伪数组对象 </li>
</ol>
<p>含义：以数组的形式来存储所有函数执行时，传入的实参。</p>
<p>如果想要 获取所有传入的实参，可以通过for循环去遍历。</p>
<p>arguments.callee: 返回正在被调用的函数。如果在递归调用时，而函数是匿名的话，那么就需要使用arguments.callee属性来实现匿名函数递归调用。</p>
<ol>
<li><p>name 存储函数的名字，ES5之后 才具有的属性</p>
</li>
<li><p>caller 返回调用函数的函数</p>
</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    fn();</div><div class="line">&#125;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log( fn.caller ); <span class="comment">// foo</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<ol>
<li>length</li>
</ol>
<p>存储函数定义形参的个数.</p>
<h3 id="函数对象的原型链"><a href="#函数对象的原型链" class="headerlink" title="函数对象的原型链"></a>函数对象的原型链</h3><p>所有的函数对象 都是 Function的实例化的对象。因此 所有函数 的构造函数 都是 Function。</p>
<p>也就说，所有函数的原型都是Function.prototype。所有函数的原型链 都是 一样一样的。</p>
<p>由于函数的原型链上所有对象 都是内置，而在实际开发时，尽量或者不推荐 随意去扩展原生对象。因此也不会去肆意替换函数的原型链。</p>
<p>那么，只要了解一下函数的原型链即可。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span>&#123;&#125;</div><div class="line"><span class="comment">// foo -&gt; Function.prototype -&gt; Object.prototype -&gt; null</span></div></pre></td></tr></table></figure>
<p>在js中，有两个内置核心函数 Function 和 Object。</p>
<p>所有函数都是Function实例化的对象，所有对象都是Object实例化的对象。</p>
<h2 id="了解Function-prototype成员"><a href="#了解Function-prototype成员" class="headerlink" title="了解Function.prototype成员"></a>了解Function.prototype成员</h2><p>Function.prototype 本质 就是一个函数类型。由于它是原型，因此 它是没有prototype属性的。</p>
<p>在之前调用函数时，可以有4种（3种调用模式 + 特殊 递归）；现在还可以使用call和apply方法来调用函数。</p>
<p>函数 可以直接调用call或者apply方法。当一个函数调用这两个方法时，会立即执行函数体内部的代码。</p>
<p>使用call和apply调用函数，目的 主要是为了 改变函数内部this的指向。</p>
<h3 id="call方法"><a href="#call方法" class="headerlink" title="call方法"></a>call方法</h3><ol>
<li>语法</li>
</ol>
<p>fn.call( thisObj, arg1 ~ argN );</p>
<ol>
<li>功能</li>
</ol>
<p>第一个参数 是 fn执行时内部this的新指向。</p>
<p>如果想要给fn传入实参，就通过第二个后面的可选形参列表。</p>
<p>如果在调用call方法时，第一个参数 传入的实际值 为 null 和 undefined的话，fn在执行时内部this 就是 window对象。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log( <span class="keyword">this</span> );</div><div class="line">    <span class="built_in">console</span>.log( <span class="keyword">this</span>.name );</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> obj = &#123; <span class="attr">name</span>: <span class="string">'guoguo'</span> &#125;;</div><div class="line">fn.call( obj );</div></pre></td></tr></table></figure>
<h3 id="apply方法"><a href="#apply方法" class="headerlink" title="apply方法"></a>apply方法</h3><ol>
<li>语法</li>
</ol>
<p>fn.apply( thisObj, [array] );</p>
<ol>
<li>功能</li>
</ol>
<p>第一个参数 和call方法第一个参数 相同，就是指定 this新指向；</p>
<p>第二个参数 是可选的数组对象。将数组元素作为fn执行的实参。</p>
<p>如果 第一个参数 传入的实际值为 null和undefined，此时fn内部this就是window对象。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"> n, m </span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log( <span class="keyword">this</span> );</div><div class="line">    <span class="built_in">console</span>.log( <span class="keyword">this</span>.name );</div><div class="line">    <span class="built_in">console</span>.log( n + m );</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> obj = &#123; <span class="attr">name</span>: <span class="string">'guoguo'</span> &#125;;</div><div class="line"><span class="comment">// fn.apply( obj );</span></div><div class="line">fn.apply( obj, [ <span class="number">6</span>, <span class="number">9</span> ] );</div></pre></td></tr></table></figure>
<h3 id="call和apply的区别"><a href="#call和apply的区别" class="headerlink" title="call和apply的区别"></a>call和apply的区别</h3><p>相同点：a 都可以通过第一个参数 来改变函数内部的this指向； b 如果第一个参数为null或undefined，此时this就是window。</p>
<p>不同点：在fn执行时传实参的方式不同，前者 通过可选的形参列表；而后者 使用可选的数组对象。</p>
<p>在实际开发时，如果想要改变this的指向问题，那么就要使用call或者apply方法。</p>
<p>怎么选择call或apply?</p>
<p>如果遇到这种情况-需要将一个数组元素当作实参 传入另一个函数的话，优先使用apply；其他情况可以优先考虑call方法。</p>
<h2 id="函数的call-apply调用模式的应用"><a href="#函数的call-apply调用模式的应用" class="headerlink" title="函数的call/apply调用模式的应用"></a>函数的call/apply调用模式的应用</h2><h3 id="改变this指向"><a href="#改变this指向" class="headerlink" title="改变this指向"></a>改变this指向</h3><p>通过在调用call或apply方法时传入第一个参数去实现改变函数内部this的指向。</p>
<h3 id="借调方法"><a href="#借调方法" class="headerlink" title="借调方法"></a>借调方法</h3><p>通过 改变某个函数或方法内部的this指向，从而间接实现其他对象调用该方法。</p>
<p>或者 使用apply方法传递实参时，是使用数组对象，根据这个特点引申出的应用。</p>
<ol>
<li>数组合并</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> arr1 = [ <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span> ];</div><div class="line"><span class="keyword">var</span> arr2 = [ <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span> ];</div><div class="line"></div><div class="line"><span class="keyword">var</span> newArr = arr1.concat( arr2 );</div><div class="line"><span class="built_in">console</span>.log( newArr );</div><div class="line"></div><div class="line"><span class="comment">// 将arr2上的所有元素添加到arr1</span></div><div class="line">arr1.push.apply( arr1, arr2 );</div><div class="line"><span class="built_in">console</span>.log( arr1 );</div></pre></td></tr></table></figure>
<ol>
<li>将2维数组 转换成 1维数组（数组扁平化处理）</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> arr = [ <span class="number">1</span>, <span class="number">2</span>, [ <span class="number">3</span>, <span class="number">4</span>, [ <span class="number">8</span>, <span class="number">9</span> ] ], [ <span class="number">4</span>, <span class="number">5</span> ] ]; <span class="comment">// 2维数组</span></div><div class="line"><span class="comment">// [ 1, 2, 3, 4, 4, 5 ]</span></div><div class="line"><span class="keyword">var</span> newArr = <span class="built_in">Array</span>.prototype.concat.apply( [], arr );</div><div class="line"><span class="built_in">console</span>.log( newArr );</div></pre></td></tr></table></figure>
<ol>
<li>伪数组对象借调数组方法</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> obj = &#123;</div><div class="line">    <span class="number">0</span>: <span class="number">1</span>,</div><div class="line">    <span class="number">1</span>: <span class="number">2</span>,</div><div class="line">    <span class="number">2</span>: <span class="number">3</span>,</div><div class="line">    length: <span class="number">3</span></div><div class="line">&#125;;</div><div class="line"></div><div class="line"><span class="comment">// 要给obj添加4，5，6,三个元素</span></div><div class="line"><span class="comment">// 原生js实现</span></div><div class="line">obj[ length ] = <span class="number">4</span>;</div><div class="line">obj.length = obj.length + <span class="number">1</span>;</div><div class="line">obj[ length ] = <span class="number">5</span>;</div><div class="line">obj.length = obj.length + <span class="number">1</span>;</div><div class="line">obj[ length ] = <span class="number">6</span>;</div><div class="line">obj.length = obj.length + <span class="number">1</span>;</div><div class="line"><span class="built_in">console</span>.log( obj );</div></pre></td></tr></table></figure>
<ol>
<li>伪数组 转换成 数组对象</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> arr = [ <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span> ];</div><div class="line"><span class="keyword">var</span> newArr = arr.slice();</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log( newArr == arr );</div></pre></td></tr></table></figure>
<ol>
<li>获取内置对象的类型</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// Array Date RegExp String Number Boolean null undefined</span></div><div class="line"><span class="comment">// 如果 获取null的类型的话，就返回 "null",</span></div><div class="line"><span class="comment">// 如果 获取undefined类型，就返回 "undefined"</span></div><div class="line"><span class="comment">// 对象类型名称：就是 其构造函数的名称小写方式。</span></div><div class="line"><span class="comment">// 获取对象的构造函数名字？</span></div><div class="line"><span class="comment">// 实现函数 去获取内置对象类型</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">getType</span>(<span class="params"> obj </span>)</span>&#123;</div><div class="line">    <span class="comment">// 判断 obj 是否为 null 和 undefined</span></div><div class="line">    <span class="keyword">if</span>( obj == <span class="literal">null</span> )&#123;</div><div class="line">        <span class="keyword">return</span> obj + <span class="string">''</span>;</div><div class="line">    &#125;</div><div class="line">    <span class="comment">// 如果obj为简单数据类型, 就可以使用typeof</span></div><div class="line">    <span class="comment">// if( typeof obj != 'object' )&#123;</span></div><div class="line">    <span class="comment">//     returnc</span></div><div class="line">    <span class="comment">// &#125; else &#123; // 如果为对象</span></div><div class="line">    <span class="comment">//     return Object.prototype.toString.call( obj ).slice( 8, -1 ).toLowerCase();</span></div><div class="line">    <span class="comment">// &#125;</span></div><div class="line">    <span class="keyword">return</span> <span class="keyword">typeof</span> obj == <span class="string">'object'</span> ?</div><div class="line">        <span class="built_in">Object</span>.prototype.toString.call( obj ).slice( <span class="number">8</span>, <span class="number">-1</span> ).toLowerCase():</div><div class="line">        <span class="keyword">typeof</span> obj;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2017/09/06/text4/" data-id="cj792tcr90000gk52qe6qt7lp" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
  
    <a href="/2017/09/06/text3/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title"></div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/09/">September 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/08/">August 2017</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2017/09/06/text4/">(no title)</a>
          </li>
        
          <li>
            <a href="/2017/09/06/text3/">(no title)</a>
          </li>
        
          <li>
            <a href="/2017/08/26/text2/">(no title)</a>
          </li>
        
          <li>
            <a href="/2017/08/26/text/">嘿嘿嘿</a>
          </li>
        
          <li>
            <a href="/2017/08/26/hello-world/">你好世界</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2017 John Doe<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>

  </div>
</body>
</html>